using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Util;

namespace G1.EngineV
{
    internal class Thread : Java.Lang.Thread
    {

        public bool Running = true;

        private ISurfaceHolder _SurfaceHolder;
        private SurfaceView _SurfaceView;

        private DateTime _LastTime;
        private double _FrameSampleTime = 0;
        private int _FrameSampleCount = 0;
        private int _FrameCountPerSecond = 0;

        public Thread( ISurfaceHolder SurfaceHolder, SurfaceView View )
        {

            _SurfaceHolder = SurfaceHolder;
            _SurfaceView = View;

            _SurfaceView.Touch += new Android.Views.View.TouchHandler( OnTouch );
            
        }

        public bool OnTouch( Android.Views.View v, MotionEvent e )
        {
            Engine.GetCurrentScene().Touch( e );
            return true;
        }

        private const int MAX_FPS = 25;
        private const int MAX_FRAME_SKIPS = 10;
        private const int FRAME_PERIOD = 1000 / MAX_FPS;  



        long next_game_tick = DateTime.Now.Ticks;

        public override void Run()
        {

            DateTime beginTime;     // the time when the cycle begun
            double timeDiff;      // the time it took for the cycle to execute
            int sleepTime;      // ms to sleep (<0 if we're behind)
            int framesSkipped;  // number of frames being skipped 

            sleepTime = 0;

            

            while ( Running )
            {

                beginTime = DateTime.Now;
                framesSkipped = 0;

                Android.Graphics.Canvas Canvas = null;

                try
                {

                    Scene Scene = Engine.GetCurrentScene();

                    Canvas = _SurfaceHolder.LockCanvas();

                    lock ( _SurfaceHolder )
                    {
                        
                        Canvas.DrawColor( Android.Graphics.Color.Orchid );



                        Scene.Update();
                        Scene.Render( Canvas );

                        if ( Engine.ShowFPS )
                        {
                            _CalculateFPS();
                            _DrawFPSCounter( Canvas );
                        }


                        Engine.Console.Render( Canvas );

                        TimeSpan ts = DateTime.Now - beginTime;

                        timeDiff = ts.TotalMilliseconds;
                        sleepTime = (int)(FRAME_PERIOD - timeDiff);

                        if ( sleepTime > 0 )
                        {
                            Java.Lang.Thread.Sleep( sleepTime );

                        }



                        while ( sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS )
                        {
                            Scene.Update();
                            sleepTime += FRAME_PERIOD;
                            framesSkipped++;
                        }

                    }

                }
                finally
                {
                    if ( Canvas != null )
                        _SurfaceHolder.UnlockCanvasAndPost( Canvas );
                }


                
            }

        }

        private void _DrawFPSCounter( Android.Graphics.Canvas Canvas )
        {

            Paint TextPaint = new Paint();
            TextPaint.Color = Color.White;

            Canvas.DrawText( _FrameCountPerSecond + " fps " + Engine.StatusMessage, 0, 20, TextPaint );

        }

        private void _CalculateFPS()
        {


            if ( _LastTime != null )
            {

                TimeSpan ts = DateTime.Now - _LastTime;

                
                _FrameSampleTime += ts.TotalMilliseconds;
                _FrameSampleCount++;

                if ( _FrameSampleCount == 10 )
                {

                    _FrameCountPerSecond = ( int )( 10000 / _FrameSampleTime );

                    _FrameSampleTime = 0;
                    _FrameSampleCount = 0;

                }
                
            }

            _LastTime = DateTime.Now;


        }



    }
}